package com.nio;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.StandardSocketOptions;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Set;

public class MultiplexerTimClient implements Runnable {

	private Selector selector;

	private volatile boolean stop;

	private static SocketChannel socketChannel;

	public MultiplexerTimClient(String ip, int port) {
		try {
			socketChannel = SocketChannel.open(new InetSocketAddress(ip, 8080));
			socketChannel.setOption(StandardSocketOptions.TCP_NODELAY, true);
			socketChannel.configureBlocking(false); // 非阻塞模式
			selector = Selector.open();
			socketChannel.register(selector, SelectionKey.OP_READ);
		} catch (IOException e) {
			e.printStackTrace();
			System.exit(1);
		}
	}

	public static void main(String[] args) throws IOException {
		MultiplexerTimClient multiplexerTimClient = new MultiplexerTimClient("127.0.0.1", 8080);
		new Thread(multiplexerTimClient).start();

		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		while (true) {
			String body = in.readLine();
			byte[] bytes = body.getBytes("utf-8");
			ByteBuffer writeBuffer = ByteBuffer.allocate(bytes.length);
			writeBuffer.put(bytes);
			writeBuffer.flip();
			while (writeBuffer.hasRemaining()) {
				socketChannel.write(writeBuffer);
			}
		}
	}

	public void stop() {
		this.stop = true;
	}

	@Override
	public void run() {
		while (!stop) {
			try {
				selector.select();
				Set<SelectionKey> selectionKeys = selector.selectedKeys();
				Iterator<SelectionKey> iterator = selectionKeys.iterator();
				SelectionKey key;
				while (iterator.hasNext()) {
					key = iterator.next();
					iterator.remove();
					try {
						handlInput(key);
					} catch (Exception e) {
						if (key != null) {
							key.cancel();
							if (key.channel() != null) {
								try {
									key.channel().close();
								} catch (Exception e1) {

								}
							}
						}
					}
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		if (selector != null) {
			try {
				selector.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	private void handlInput(SelectionKey key) throws IOException {
		if (!key.isValid()) {
			return;
		}
		// read data
		if (key.isReadable()) {
			SocketChannel socketChannel = (SocketChannel) key.channel();
			ByteBuffer readBuffer = ByteBuffer.allocate(1024);
			int readLength = socketChannel.read(readBuffer);
			if (readLength > 0) {
				readBuffer.flip(); // 切换到读状态
				CharBuffer charBuffer = Charset.forName("utf-8").decode(readBuffer);
				String body = charBuffer.toString();
				System.out.println("The Time Client received order: " + body);
			} else if (readLength < 0) {
				key.cancel();
				socketChannel.close();
			} else {
				// read 0 byte; ignore
			}
		}
	}
}
